import { ref, reactive, computed, watchEffect } from 'vue'
import anime from '@/anime.es.js'
export default function useSort() {
  const arr = reactive([4, 6, 2, 8, 10, 7, 12, 11, 5, 3])
  const arrDefaultLen = arr.length
  const boundary = ref(arr.length - 1)
  const sortingArr = ref([] as number[])
  const exchangeArr = ref([] as number[])

  const sorting = ref(false)

  async function myWait(duration = 400) {
    return new Promise((resolve) => setTimeout(resolve, duration))
  }

  const showCode = computed(
    () =>
      `arr[${sortingArr.value[0]}] > arr[${sortingArr.value[1]}] = ${arr[sortingArr.value[0]] > arr[sortingArr.value[1]]}`
  )

  const arrToString = computed(() => `数组：arr -> [${arr.toString()}]`)

  async function onSort() {
    if (sorting.value) return
    sorting.value = true
    const len = arr.length
    for (let i = 0; i < len - 1; i++) {
      boundary.value = len - 1 - i
      for (let j = 0; j < boundary.value; j++) {
        sortingArr.value = [j, j + 1]
        await myWait(500)
        if (arr[j] > arr[j + 1]) {
          exchangeArr.value = [j, j + 1]
          await myWait(600)
        }
      }
    }
    boundary.value = -1
    sorting.value = false
    sortingArr.value = []
  }
  function onReset() {
    arr.sort(() => Math.random() - 0.5)
    boundary.value = arr.length - 1
    sortingArr.value = []
  }

  watchEffect(async () => {
    if (exchangeArr.value.length) {
      if (exchangeArr.value.length === 2) {
        // 视觉交换位置
        const [a, b] = exchangeArr.value
        const lis: NodeList = document.querySelectorAll('.sort-ul > li')
        const ela = lis[a] as HTMLLIElement
        const elb = lis[b] as HTMLLIElement
        await Promise.all([
          new Promise((resolve) => {
            anime({
              targets: ela,
              translateX: elb.offsetLeft - ela.offsetLeft,
              duration: 500,
              easing: 'linear',
              complete: () => {
                ela.style.cssText = ''
                resolve(1)
              }
            })
          }),
          new Promise((resolve) => {
            anime({
              targets: elb,
              translateX: ela.offsetLeft - elb.offsetLeft,
              duration: 500,
              easing: 'linear',
              complete: () => {
                elb.style.cssText = ''
                resolve(1)
              }
            })
          })
        ])
        exchangeArr.value.push(-1)
      } else if (exchangeArr.value.length === 3) {
        // 物理交换位置
        const [a, b] = exchangeArr.value
        const temp = arr[b]
        arr[b] = arr[a]
        arr[a] = temp
      }
    }
  })

  return {
    arr,
    boundary,
    sortingArr,
    exchangeArr,
    sorting,
    showCode,
    arrToString,
    onSort,
    onReset,
    myWait,
    arrDefaultLen
  }
}
